import cv2
import numpy as np
from PyQt5.Qt import *
from PyQt5.QtCore import *


def cvToQImage(data):
    # 8-bits unsigned, NO. OF CHANNELS=1
    if data.dtype == np.uint8:
        channels = 1 if len(data.shape) == 2 else data.shape[2]
    if channels == 3:  # CV_8UC3
        # Copy input Mat
        # Create QImage with same dimensions as input Mat
        img = QImage(data, data.shape[1], data.shape[0], data.strides[0], QImage.Format_RGB888)
        return img.rgbSwapped()
    elif channels == 1:
        # Copy input Mat
        # Create QImage with same dimensions as input Mat
        img = QImage(data, data.shape[1], data.shape[0], data.strides[0], QImage.Format_Indexed8)
        return img


class Camera(QObject):
    sendPicture = pyqtSignal(QImage)

    def __init__(self, parent=None):
        super(Camera, self).__init__(parent)

        # 将Camera下所有属性、方法放置入一个子线程
        self.thread = QThread()
        self.moveToThread(self.thread)
        # 获取该线程所对应的摄像头硬件ID
        self.timer = QTimer()
        self.init_timer()
        self.cap = cv2.VideoCapture()
        self.camera_num = 0
        # 初始化检测算子为None，在self.set_detector方法中设置Camera的检测算子
        self.detector = None
        self.detect_flag = 0
        self.needflip = 0

    # 设置Camera的检测算子,传参为检测算子相应的类
    def set_detector(self, detector):
        self.detector = detector()

    def init_timer(self):
        self.timer.setInterval(20)
        self.timer.timeout.connect(self.display)

    def set_cam_number(self, n):
        self.camera_num = n

    def open_camera(self):
        self.cap.open(self.camera_num)
        self.cap.set(4, 480)
        self.cap.set(3, 640)
        self.timer.start()
        self.thread.start()

    def close_camera(self):
        self.cap.release()

    def display(self):
        # time.sleep(2)
        flag, image = self.cap.read()

        # 确认是否需要左右翻转
        if self.needflip == 1:
            image = cv2.flip(image, 1)
        else:
            pass

        # 检查是否进行检测
        if self.detect_flag == 1:
            if self.detector != None:
                image = self.detector.detect(image)
            else:
                pass
        else:
            pass

        showImage = cvToQImage(image)
        self.sendPicture.emit(showImage)
